---
title: Traefik
description: Deploy Kaneo with Traefik
---
import { Step, Steps } from 'fumadocs-ui/components/steps';

This guide explains how to deploy Kaneo using Traefik as a reverse proxy. This setup is ideal for production environments where you want to expose Kaneo through a domain name with HTTPS.

## Prerequisites

- A server with Docker and Docker Compose installed
- A domain name pointing to your server
- Basic knowledge of Traefik configuration

<Steps>
<Step>
Create a `compose.yml` file with the following content:
</Step>

```yaml
services:
  traefik:
    image: "traefik:v3.3"
    container_name: "traefik"
    command:
      - "--providers.docker=true"
      - "--entryPoints.web.address=:80"
    ports:
      - "80:80"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    networks:
      - traefik-net

  postgres:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: kaneo
      POSTGRES_USER: kaneo_user
      POSTGRES_PASSWORD: kaneo_password
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - traefik-net
    restart: unless-stopped

  backend:
    image: ghcr.io/usekaneo/api:latest
    environment:
      JWT_ACCESS: "your_secure_jwt_token"
      DATABASE_URL: "postgresql://kaneo_user:kaneo_password@postgres:5432/kaneo"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.backend.rule=Host(`api.your-domain.com`)"
      - "traefik.http.routers.backend.entrypoints=web"
      - "traefik.http.services.backend.loadbalancer.server.port=1337"
    depends_on:
      - postgres
    networks:
      - traefik-net
    restart: unless-stopped

  frontend:
    image: ghcr.io/usekaneo/web:latest
    environment:
      KANEO_API_URL: "http://api.your-domain.com"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.frontend.rule=Host(`your-domain.com`)"
      - "traefik.http.routers.frontend.entrypoints=web"
      - "traefik.http.services.frontend.loadbalancer.server.port=5173"
    depends_on:
      - backend
    networks:
      - traefik-net
    restart: unless-stopped

networks:
  traefik-net:
    driver: bridge

volumes:
  postgres_data:
```

<Step>
Start the containers:

```bash
docker compose up -d
```
</Step>

<Step>
Configure your DNS settings to point both `your-domain.com` and `api.your-domain.com` to your server's IP address.
</Step>

<Step>
You should now be able to access Kaneo at `http://your-domain.com` and the API at `http://api.your-domain.com`. 🎉
</Step>
</Steps>

## Alternative Configuration: Single Domain with Path-Based Routing

If you prefer to use a single domain with path-based routing, you can use the following configuration:

<Steps>
<Step>
Create a `compose.yml` file with the following content:
</Step>

```yaml
services:
  traefik:
    image: "traefik:v3.3"
    container_name: "traefik"
    command:
      - "--providers.docker=true"
      - "--entryPoints.web.address=:80"
    ports:
      - "80:80"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    networks:
      - traefik-net

  postgres:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: kaneo
      POSTGRES_USER: kaneo_user
      POSTGRES_PASSWORD: kaneo_password
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - traefik-net
    restart: unless-stopped

  backend:
    image: ghcr.io/usekaneo/api:latest
    environment:
      JWT_ACCESS: "your_secure_jwt_token"
      DATABASE_URL: "postgresql://kaneo_user:kaneo_password@postgres:5432/kaneo"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.backend.rule=Host(`your-domain.com`) && PathPrefix(`/api`)"
      - "traefik.http.routers.backend.entrypoints=web"
      - "traefik.http.middlewares.backend-stripprefix.stripprefix.prefixes=/api"
      - "traefik.http.routers.backend.middlewares=backend-stripprefix"
      - "traefik.http.services.backend.loadbalancer.server.port=1337"
    depends_on:
      - postgres
    networks:
      - traefik-net
    restart: unless-stopped

  frontend:
    image: ghcr.io/usekaneo/web:latest
    environment:
      KANEO_API_URL: "http://your-domain.com/api"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.frontend.rule=Host(`your-domain.com`)"
      - "traefik.http.routers.frontend.entrypoints=web"
      - "traefik.http.services.frontend.loadbalancer.server.port=80"
    depends_on:
      - backend
    networks:
      - traefik-net
    restart: unless-stopped

networks:
  traefik-net:
    driver: bridge

volumes:
  postgres_data:
```

<Step>
Start the containers:

```bash
docker compose up -d
```
</Step>

<Step>
Configure your DNS settings to point `your-domain.com` to your server's IP address.
</Step>

<Step>
You should now be able to access Kaneo at `http://your-domain.com` and the API will be accessible at `http://your-domain.com/api`. 🎉
</Step>
</Steps>